package com.lagou.monitor;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 *
 概念：TP指标: 指在一个时间段内，统计该方法每次调用所消耗的时间，并将这些时间按从小到大的顺序进行排序,并取出结果为：总次数 * 指标数 = 对应TP指标的值， 在取出排序好的时间。

 TP50：指在一个时间段内（如5分钟），统计该方法每次调用所消耗的时间，并将这些时间按从小到大的顺序进行排序，取第50%的那个值作为TP50 值；
 *
 */
public class TPMonitorThread implements Runnable {

    // 每隔5s打印一次最近1分钟内每个方法的TP90、TP99的耗时情况
    @Override
    public void run() {
        try {
            System.out.println("性能播报: .....");
            long now = System.currentTimeMillis();
            long minuteBefore = now - TimeUnit.SECONDS.toMillis(1); //1分钟
            // TP90 、TP99
            for(Map.Entry<String, List<TPMonitorMeta>> entry : TPMonitorHolder.map.entrySet()) {
                String method = entry.getKey();
                List<TPMonitorMeta> metas = entry.getValue();

                List<TPMonitorMeta> lastMetas = new ArrayList<>();
                for (TPMonitorMeta meta : metas) {
                    if(meta.getRequestTime() >= minuteBefore) {
                        lastMetas.add(meta);
                    }
                }
                System.out.println("TP:准备排序");
                // 按照请求耗时排序
                Collections.sort(lastMetas, new Comparator<TPMonitorMeta>() {
                    @Override
                    public int compare(TPMonitorMeta o1, TPMonitorMeta o2) {
                        return (int) (o1.getCostTime() - o2.getCostTime());
                    }
                });
                System.out.println("TP:排序完成，开始计算");
                if(lastMetas.size() == 0) {
                    System.out.println(String.format("TP：服务: %s , TP90：%s", method, "unknow"));
                    System.out.println(String.format("TP：服务: %s , TP99：%s", method, "unknow"));
                    return;
                }
                // 开始计算 TP指标
                long tp90 = getTP(lastMetas, 0.90);
                System.out.println("TP90:" + tp90);
                long tp99 = getTP(lastMetas, 0.99);
                System.out.println(String.format("TP：服务: %s , TP90：%s", method, tp90+"ms"));
                System.out.println(String.format("TP：服务: %s , TP99：%s", method, tp99+"ms"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private long getTP(List<TPMonitorMeta> metas, double tp) {
        int count = metas.size();
        double t = count * tp;
        int p = (int) Math.ceil(t);
        int idx = p;
        if(p >= count) {
            idx = p-1;
        }
        if(p < 0) {
            p = 0;
        }
        TPMonitorMeta meta = metas.get(idx);
        return meta.getCostTime();
    }

    public static void main(String[] args) {
        double f = 3.96f;
        System.out.println(Math.ceil(f));

    }
}
